#ifndef _MS2LSTAT_H_
#define _MS2LSTAT_H_

#include <clx/libECM.h>
#include <clx/ecm_list.h>

#include "libms2sim.h"
#include "ms2lstat_mod.h"

#define ERR(fmt, ...)	ECMERR("ERR: ms2lstat: " fmt, ## __VA_ARGS__)

typedef struct {
	char	*uri;
	ecm_uint32	mid;
	ecm_uint64	length;
	ecm_uint64	size;
	ecm_uint32	n_accessed;
	struct list_head	list;
	struct list_head	list_size;
} media_t;

typedef struct {
	ecm_uint32	cid;
	char	*idstr;
} client_t;

typedef struct {
	ecm_uint32	pid;
	char	*player_desc;
	ecm_uint32	accessed_count;
} player_t;

typedef struct {
	ecm_uint32	tick_start;
	ecm_uint32	tick_end;
	ecm_uint32	startstamp;
	ecm_uint32	endstamp;
	ecm_int32	playback_rate;
	struct list_head	list;
} access_t;

typedef struct {
	ecm_uint32	sid;
	ecm_uint32	mid;
	ecm_uint32	cid;

	struct list_head	accesses;
	struct list_head	list_ia;
} session_t;

typedef struct {
	ecm_uint32	n_max;
	ecm_uint32	n_count;
	ecm_uint32	*data;
} hist_t;

extern char	*lparser_modpath;
extern ECMBOOL	mod_has_error;
extern char	*mod_errmsg;
extern ECMBOOL	stop_on_error;
extern ECMBOOL	suppress_display_error;

extern lparser_op_t	*lparser_op;

extern ecm_uint64	n_logs;
extern ecm_uint64	n_error_logs;

extern ecm_uint32	start_tick, end_tick;

extern ecm_int32	stat_iatime;
extern ecm_uint32	stat_mid;
extern ecm_uint32	stat_media_rank;

extern ecm_uint32	max_hourly_n_arrivals;

extern ecm_hashtable_t	n_clients;
extern ecm_hashtable_t	n_medias;

extern char	*confpath;

extern char	*logbase;
extern ECMBOOL	no_suffix_logging;

extern ecm_uint32	arrival_duration;
extern ecm_uint32	start_hourzone, end_hourzone;

extern ecm_uint32	wday_start;
extern ecm_int32	exclude_day;

extern ecm_uint32	session_gap;

extern ECMBOOL init_mod(void);

ECMBOOL parse_logs(ecm_strlist_t files);

extern ECMBOOL init_media(void);
extern ecm_uint32 get_media_id(const char *uri);
extern media_t *get_media(ecm_uint32 mid);
extern ecm_uint32 get_media_rank(ecm_uint32 mid);
extern ECMBOOL update_media_info(ecm_uint32 mid, ecm_uint64 length, ecm_uint64 size);
extern void incr_media_access(session_t *session);
extern void report_media_result(FILE *fp);

extern ECMBOOL init_client(void);
extern ecm_uint32 get_client_id(const char *idstr);
extern client_t *get_client(ecm_uint32 cid);
extern void report_client_result(FILE *fp);

extern ECMBOOL init_player(void);
extern ecm_uint32 get_player_id(const char *idstr);
extern void report_player_result(FILE *fp);

extern ECMBOOL init_lstatconf(void);

extern ECMBOOL init_session(void);
extern void update_session(lent_t *lent);
extern void report_session_result(FILE *fp);

extern ecm_double get_interseek_time(session_t *session);
extern ecm_uint32 get_sesslen(session_t *sesson);

extern void add_arrival(session_t *session);
extern void del_arrival(session_t *session);
extern void report_arrival_result(FILE *fp);
extern ECMBOOL init_arrival(void);

extern ecm_int32 get_session_interarrival(session_t *session);
extern ecm_double get_media_peak_interarrival(ecm_uint32 mid);

extern void report_request_result(FILE *fp);
extern void update_request(lent_t *lent);

extern hist_t *create_hist(void);
extern void add_hist(hist_t *hist, ecm_uint32 idx, ecm_uint32 cnt);
extern void free_hist(hist_t *hist);

extern void report_result(void);
extern FILE *setup_logging(const char *name);

#ifdef MSM_DEBUG

extern ecm_dbg_t	ms2lstat_dbg;

#define DBG_ALL		0xffff
#define DBG_NORMAL_LOG	0x0001
#define DBG_FORWARD_LOG	0x0002
#define DBG_BACKWARD_LOG	0x0004

#define DBG(dbgset, fmt, ...)	ECMDBG(ms2lstat_dbg, dbgset, fmt, ## __VA_ARGS__)

const char *dbg_lent(lent_t *lent, session_t *session);

#else

#define DBG(dbgset, fmt, ...)	do {} while (0)

#endif

#endif
